Skip to content

docs: timers guide#9

Merged
marc0olo merged 4 commits into
mainfrom
docs/guides-backends-timers
Mar 16, 2026
Merged

docs: timers guide#9
marc0olo merged 4 commits into
mainfrom
docs/guides-backends-timers

Conversation

@raymondk
Copy link
Copy Markdown
Collaborator

@raymondk raymondk commented Mar 13, 2026

Summary

  • Covers timer APIs for Rust (ic-cdk-timers v1.0.0) and Motoko (mo:core/Timer v2.1.0): one-shot, recurring, serial, and cancellation
  • System time API (ic_cdk::api::time() / Time.now()) with per-message consistency guarantee
  • Common patterns: periodic cleanup, data aggregation, timed state transitions
  • Upgrade handling: timers cleared on upgrade, re-register in post_upgrade/postupgrade
  • Cycle costs, idempotency requirements, CDK rate limits (250 global, 5 per timer)
  • Heartbeats (legacy) with migration guide
  • FAQ: DTS support, await behavior, overlapping execution
  • Limitations: relative time only, security warning, resolution similar to block rate
  • Time conversion packages (Motoko mops, Rust crates)

All Rust snippets verified against ic-cdk-timers v1.0.0 (set_timer takes futures, set_timer_interval takes FnMut() -> Future). All Motoko snippets verified against motoko-core v2.1.0 and compiler v1.3.0.

Sync recommendation

Informed by dfinity/portal periodic-tasks-timers.mdx + time-and-timestamps.mdx, dfinity/cdk-rs ic-cdk-timers/src/lib.rs, and caffeinelabs/motoko-core src/Timer.mo

@marc0olo
Copy link
Copy Markdown
Member

Review: Timers

Must fix

  • Missing content brief topics — "scheduled data aggregation" and "timed state transitions": The content brief specifically asks for "Common patterns: periodic cleanup, scheduled data aggregation, timed state transitions." The page only mentions periodic cleanup in a code comment but doesn't show any of these patterns as concrete examples. At minimum, a "Common patterns" section with brief descriptions and skeleton snippets (or links to examples) would satisfy the brief.

  • Portal FAQ content omitted: The portal source (periodic-tasks-timers.mdx:112-119) has three useful FAQs that developers will search for:

    1. Do timers support deterministic time slicing (DTS)? (Yes)
    2. What happens if a timer handler awaits a call? (Normal await rules apply)
    3. What happens if a 1s periodic timer executes for 2s?

    These are exactly the "hard parts" a developer would struggle with. They should be included (or at least the await-point behavior, which is a common footgun).

  • Motoko postupgrade claim needs verification: The page says "read it from stable variables in postupgrade" and uses system func postupgrade(). The portal source and the mo:base/Timer examples use canister_post_upgrade semantics. Since the page targets mo:core (the modern library), postupgrade may be correct for persistent actors — but this should be verified or flagged with <!-- Needs human verification --> since there's no .sources/ reference confirming this exact spelling/syntax for persistent actors.

Suggestions

  • "A duration of 0 in Motoko will only fire once, not repeatedly" — This claim appears in the "Recurring timers" section but has no source in .sources/. If true, it's useful; if not, it's misleading. Either verify it or flag it with <!-- Needs human verification -->.

  • Heartbeat interval: The page says "~1 second" but the portal says "intervals close to the blockchain finalization rate (1s)". Consider matching the portal's phrasing since the actual interval is implementation-defined and not guaranteed to be 1s.

  • Time conversion section missing: The writing note says "Also cover ic0.time() behavior and timestamps (portal: time-and-timestamps.mdx) — developers looking for 'how does time work on ICP' will land here." The "System time" section covers ic_cdk::api::time() and Time.now(), which is good. But the portal's timestamp page also covers DateTime conversions and conversion packages (time crate, mops.one/time, mops.one/datetime). Consider at least mentioning these exist and linking to them, since this page is where "how does time work" developers will land.

  • "Advanced scheduling" limitation omitted: The portal mentions that CDK timers use relative time only — absolute scheduling requires manual calculation or a third-party library. This is a practical limitation worth including.

  • Funnel check: The page ends with a link to the Rust periodic tasks example, which is fine, but there's no "what's next" guidance. A brief closing like "For canister lifecycle hooks referenced above, see Canister lifecycle" would help readers continue.

Verified

  • All internal links resolve: ../../concepts/timers.md, ../canister-management/lifecycle.md, ../../reference/cycles-costs.md all exist
  • External URLs are correct: github.com/dfinity/examples/tree/master/rust/periodic_tasks matches .sources/examples, learn.internetcomputer.org is an allowed external link
  • No dfx references — clean
  • No .mdx/JSX — plain markdown throughout
  • Motoko uses mo:core/ (not mo:base/) per content rules
  • Rust code patterns (ic_cdk_timers::set_timer, set_timer_interval, clear_timer, ic_cdk::spawn for async) verified against .sources/examples/rust/periodic_tasks/timer/src/lib.rs
  • Frontmatter is complete and consistent with body content
  • Sync recommendation present: <!-- Upstream: informed by dfinity/portal ... -->
  • Code snippets are all under 30 lines inline

raymondk and others added 3 commits March 16, 2026 14:41
Review feedback (marc0olo):
- Add "Common patterns" section (cleanup, data aggregation, state transitions)
- Add FAQ section from portal (DTS, await behavior, overlapping timers)
- Fix heartbeat interval wording to match portal ("close to finalization rate")
- Add time conversion packages (Motoko mops, Rust crates)
- Add limitations section (relative time only, security warning, resolution)
- Add "What's next" links to lifecycle, concepts, and costs pages

Source-verified fixes (from .sources/cdk-rs and .sources/motoko-core):
- Update all Rust snippets to ic-cdk-timers v1.0.0 API: set_timer takes
  a future (async {}), set_timer_interval takes FnMut() -> Future (|| async {})
- Remove obsolete ic_cdk::spawn pattern (no longer needed)
- Add set_timer_interval_serial for state-mutating periodic tasks
- Add idempotency warning and CDK rate limits (250 global, 5 per timer)
- Verify Motoko postupgrade spelling and duration 0 behavior against source
The previous wording claimed system time is the same for all messages
in a round. The actual guarantee from motoko-core Time.mo:42 is that
time is constant within a single message execution only.
@marc0olo marc0olo force-pushed the docs/guides-backends-timers branch from 1e7a6e5 to 21bf406 Compare March 16, 2026 13:47
@marc0olo
Copy link
Copy Markdown
Member

Feedback addressed:

From review:

  • Added "Common patterns" section (periodic cleanup, data aggregation, timed state transitions, heartbeat migration)
  • Added FAQ section from portal (DTS support, await behavior, overlapping timer execution)
  • Fixed heartbeat interval wording ("close to blockchain finalization rate")
  • Added time conversion packages (Motoko mops, Rust crates)
  • Added "Limitations" section (relative time only, security warning, timer resolution)
  • Added "What's next" links (lifecycle, concepts, costs)

Source-verified fixes (from new .sources/cdk-rs and .sources/motoko-core submodules):

  • Updated all Rust snippets to ic-cdk-timers v1.0.0 API: set_timer takes a future (async {}), set_timer_interval takes FnMut() -> Future (|| async {})
  • Removed obsolete ic_cdk::spawn pattern
  • Added set_timer_interval_serial for state-mutating periodic tasks
  • Added idempotency warning and CDK rate limits (250 global, 5 per interval timer)
  • Corrected system time guarantee (constant per message execution, not per round)
  • Verified postupgrade spelling and duration 0 behavior against compiler/library source

Verification status: All 20 technical claims verified against .sources/ (cdk-rs, motoko-core, motoko compiler, portal).

@marc0olo marc0olo merged commit 2d48373 into main Mar 16, 2026
1 check passed
@marc0olo marc0olo deleted the docs/guides-backends-timers branch March 16, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants